#pragma once

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

using namespace std;

// #define MySelf 1
// #define MySelf=1

const std::string blank_space_sep = " ";
const std::string protocol_sep = "\n";

// response和request都需要使用decode和encode

// "len"\n"x op y"\nXXXXXX
// "protocolnumber"\n"len"\n"x op y"\nXXXXXX

// content-->package
string Encode(string &content)
{
    string package = to_string(content.size());

    package += protocol_sep;
    package += content;
    package += protocol_sep;

    return package;
}

// package-->content
bool Decode(string &package, string *content)
{
    size_t pos = package.find(protocol_sep);
    if (pos == std::string::npos)
        return false;

    std::string len_str = package.substr(0, pos); // 左闭右开
    std::size_t len = std::stoi(len_str);
    size_t total_len = len + len_str.size() + 2;
    if (total_len > package.size())
        return false;

    // 获取内容与移除已经获取的内容
    *content = package.substr(pos + 1, len);
    package.erase(0, total_len);
    return true;
}

// 序列化的最常用的方案：json, protobuf

class Request
{
public:
    Request(int x, int y, char op) : x(x), y(y), op(op) {}
    Request() {} // 默认构造函数

public:
    // 序列化"x op y"
    bool Serialize(string *out)
    {
#ifdef MySelf
        Json::Value root;
        root["x"] = x;
        root["y"] = y;
        root["op"] = op;
        // Json::FastWriter w;
        Json::StyledWriter w;
        *out = w.write(root);
#else
        string content;
        content += to_string(x) + blank_space_sep + op + blank_space_sep + to_string(y);

        *out = content;
#endif
        return true;
    }

    // 反序列化"x op y"
    bool Deserialize(string &in)    //拆分 + 安全检查
    {

#ifdef MySelf
        Json::Value root;
        Json::Reader r;
        r.parse(in, root);

        x = root["x"].asInt();
        y = root["y"].asInt();
        op = root["op"].asInt();

#else
        std::size_t left = in.find(blank_space_sep);
        if (left == std::string::npos)
            return false;
        std::string part_x = in.substr(0, left);

        std::size_t right = in.rfind(blank_space_sep);
        if (right == std::string::npos)
            return false;
        std::string part_y = in.substr(right + 1);

        if (left + 2 != right)
            return false;
        op = in[left + 1];
        x = std::stoi(part_x);
        y = std::stoi(part_y);
#endif
        return true;
    }
    
    void DebugPrint()
    {
        std::cout << "新请求构建完成:  " << x << op << y << "=?" << std::endl;
    }

public:        
        // x op y
        int x;
        int y;
        char op; // + - * / %
};


class Response
{
public:
    Response(int result, int code) : result(result), code(code) {}
    Response() {} // 默认构造函数

public:
    // 序列化"result code"
    bool Serialize(string *out)
    {
        // "result code"
        // 构建报文的有效载荷
        std::string s = std::to_string(result);
        s += blank_space_sep;
        s += std::to_string(code);
        *out = s;
        return true;
    }

    bool Deserialize(string &in)    //拆分 + 安全检查
    {
        std::size_t pos = in.find(blank_space_sep);
        if (pos == std::string::npos)
            return false;
        std::string part_left = in.substr(0, pos);
        std::string part_right = in.substr(pos+1);

        result = std::stoi(part_left);
        code = std::stoi(part_right);

        return true;
    }
  
    void DebugPrint()
    {
        std::cout << "结果响应完成, result: " << result << ", code: "<< code << std::endl;
    }
public:
    int result;
    int code; // 0，可信，否则!0具体是几，表明对应的错误原因
};